package org.setaria.container
{
	
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.core.mx_internal;
	import mx.events.CloseEvent;
	import mx.events.FlexEvent;
	import mx.events.SandboxMouseEvent;
	import mx.managers.CursorManager;
	import mx.managers.SystemManager;
	import mx.utils.BitFlagUtil;
	
	import org.setaria.event.ResizeSetariaEvent;
	import org.setaria.skins.container.TitleWindowSkin;
	
	import spark.components.Button;
	import spark.components.TitleWindow;
	import spark.events.TitleWindowBoundsEvent;
	import spark.skins.spark.TitleWindowSkin;
	
	[Event(name="restore", type="org.monster.simple.event.ResizeSimpleEvent")]
	[Event(name="maximize", type="org.monster.simple.event.ResizeSimpleEvent")]
	[Event(name="minimize", type="org.monster.simple.event.ResizeSimpleEvent")]
	
	public class SetariaTitleWindow extends TitleWindow
	{
		
		public static const STATE_NORMAL:String = "normal";
		public static const STATE_MAXIMIZE:String = "maximize";
		public static const STATE_MINIMIZE:String = "minimize";
		
		[Embed(source="/org/setaria/assets/container/resizeCursorH.gif")]
		private static var DEFAULT_RESIZE_CURSOR_HORIZONTAL:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorTLBR.gif")]
		private static var DEFAULT_RESIZE_CURSOR_TL_BR:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorTRBL.gif")]
		private static var DEFAULT_RESIZE_CURSOR_TR_BL:Class;
		
		[Embed(source="/org/setaria/assets/container/resizeCursorV.gif")]
		private static var DEFAULT_RESIZE_CURSOR_VERTICAL:Class;
		
		private var _maximizable:Boolean=true;
		
		private var _minimizable:Boolean=true;
		
		private var _resizable:Boolean=true;
		
		private var _close:Boolean = true;
		
		
		
		
		
		//窗口原大小
		private var normalWidth:int,normalHeight:int;
		//窗口原位置
		private var normalX:int,normalY:Number;
		
		private var dragAmountX:Number;
		
		private var dragAmountY:Number;
		
		private var dragMaxX:Number;
		
		private var dragMaxY:Number;
		
		private var dragStartMouseX:Number;
		
		private var dragStartMouseY:Number;
		
		//窗口大小状态
		public var sizeState:String = SetariaTitleWindow.STATE_NORMAL;
		
		public function SetariaTitleWindow()
		{
			super();
//			this.styleName= "SimpleTitleWindow";
//			setStyle("skinClass",org.setaria.skins.container.TitleWindowSkin);
		}
		
		[SkinPart(required="false")]
		public var restoreButton:Button;//
		[SkinPart(required="false")]
		public var maximizeButton:Button;//
		[SkinPart(required="false")]
		public var minimizeButton:Button;//
		
		private var currentResizeHandle:Button;
		private var savedWindowRect:Rectangle;
		
		[SkinPart(required="false")]
		public var bottomLeftButton:Button;//
		[SkinPart(required="false")]
		public var bottomButton:Button;//
		[SkinPart(required="false")]
		public var bottomRightButton:Button;//
		[SkinPart(required="false")]
		public var leftButton:Button;//
		[SkinPart(required="false")]
		public var rightButton:Button;//
		[SkinPart(required="false")]
		public var topButton:Button;//
		[SkinPart(required="false")]
		public var topLeftButton:Button;//
		[SkinPart(required="false")]
		public var topRightButton:Button;//
		
		
		/**
		 *  @private
		 */
		override protected function partAdded(partName:String, instance:Object) : void
		{
			super.partAdded(partName, instance);
			
			if (instance == minimizeButton)
			{
				minimizeButton.focusEnabled = false;
				if(showMinimizButton){
					minimizeButton.addEventListener(MouseEvent.CLICK, minimizeButton_clickHandler);   
				}else{
					minimizeButton.visible = false;
					minimizeButton.enabled = false;
					minimizeButton.includeInLayout = false;
				}
			}
			else if (instance == restoreButton)
			{
				restoreButton.focusEnabled = false;
				restoreButton.visible = false;
				restoreButton.enabled = false;
				if(showMaximizButton){
					restoreButton.addEventListener(MouseEvent.CLICK, restoreButton_clickHandler);   
				}else{
					restoreButton.includeInLayout = false;
				}
			}
			else if (instance == maximizeButton)
			{
				maximizeButton.focusEnabled = false;
				if(showMaximizButton){
					maximizeButton.addEventListener(MouseEvent.CLICK, maximizeButton_clickHandler);   
				}else{
					maximizeButton.visible = false;
					maximizeButton.enabled = false;
					maximizeButton.includeInLayout = false;
				}
			}
			else if (instance == topButton)
			{
				if(resizeEnabled)
				{
					topButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					topButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					topButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					topButton.visible=false;
					topButton.enabled=false;
					
				}
			}
			else if (instance == bottomButton)
			{
				if(resizeEnabled)
				{
					bottomButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					bottomButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					bottomButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					bottomButton.visible=false;
					bottomButton.enabled=false;
				}
			}
			else if (instance == leftButton)
			{
				if(resizeEnabled)
				{
					leftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					leftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					leftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					leftButton.visible=false;
					leftButton.enabled=false;
				}
			}
			else if (instance == rightButton)
			{
				if(resizeEnabled)
				{
					rightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					rightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					rightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					rightButton.visible=false;
					rightButton.enabled=false;
				}
			}
			else if (instance == topLeftButton)
			{
				if(resizeEnabled)
				{
					topLeftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
					topLeftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
					topLeftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
				}
				else
				{
					topLeftButton.visible=false;
					topLeftButton.enabled=false;
				}
			}
			else if (instance == topRightButton)
			{
				if(resizeEnabled)
				{
					topRightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					topRightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					topRightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					topRightButton.visible=false;
					topRightButton.enabled=false;
				}
			}
			else if (instance == bottomLeftButton)
			{
				if(resizeEnabled)
				{
					bottomLeftButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					bottomLeftButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					bottomLeftButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					bottomLeftButton.visible=false;
					bottomLeftButton.enabled=false;
				}
			}
			else if (instance == bottomRightButton)
			{
				if(resizeEnabled)
				{
					bottomRightButton.addEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver);
					bottomRightButton.addEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown);
					bottomRightButton.addEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut);
				}
				else
				{
					bottomRightButton.visible=false;
					bottomRightButton.enabled=false;
				}
			}
			
		}
		
		/**
		 *  @private
		 */
		override protected function partRemoved(partName:String, instance:Object):void
		{
			super.partRemoved(partName, instance);
			
			if (instance == minimizeButton)
				minimizeButton.removeEventListener(MouseEvent.CLICK, minimizeButton_clickHandler);
			
			else if (instance == restoreButton)
				restoreButton.removeEventListener(MouseEvent.CLICK, restoreButton_clickHandler);
			
			else if (instance == maximizeButton)
				maximizeButton.removeEventListener(MouseEvent.CLICK, maximizeButton_clickHandler);
			else if (instance == topButton)
			{
				topButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomButton)
			{
				bottomButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == leftButton)
			{
				leftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				leftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				leftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == rightButton)
			{
				rightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				rightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				rightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == topLeftButton)
			{
				topLeftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topLeftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topLeftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == topRightButton)
			{
				topRightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				topRightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				topRightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomLeftButton)
			{
				bottomLeftButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomLeftButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomLeftButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			else if (instance == bottomRightButton)
			{
				bottomRightButton.removeEventListener(MouseEvent.ROLL_OVER, resizeButtonRollOver)
				bottomRightButton.removeEventListener(MouseEvent.MOUSE_DOWN, resizeButtonDown)
				bottomRightButton.removeEventListener(MouseEvent.ROLL_OUT, resizeButtonRollOut)
			}
			
		}
		
		
		protected function minimizeButton_clickHandler(event:MouseEvent):void
		{
			dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.MINIMIZE));
		}
		
		protected function restoreButton_clickHandler(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_MAXIMIZE || sizeState == SetariaTitleWindow.STATE_MINIMIZE)
			{
				this.x=this.normalX;
				this.y=this.normalY;
				this.width=this.normalWidth;
				this.height=this.normalHeight;
				sizeState=SetariaTitleWindow.STATE_NORMAL;
				restoreButton.visible=false;
				restoreButton.enabled=false;
				maximizeButton.visible=true;
				maximizeButton.enabled=true;
				dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.RESTORE));
			}
		}
		
		protected function maximizeButton_clickHandler(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				normalX=this.x;
				normalY=this.y;
				normalHeight=this.height;
				normalWidth=this.width;
				
				this.x=0;
				this.y=0;
				if(this.parent is SystemManager){
					this.height = this.parentApplication.height;
					this.width = this.parentApplication.width;
				}else{
					this.height=this.parent.height;
					this.width=this.parent.width;
				}
				sizeState=SetariaTitleWindow.STATE_MAXIMIZE;
				maximizeButton.visible=false;
				maximizeButton.enabled=false;
				restoreButton.visible=true;
				restoreButton.enabled=true;
				dispatchEvent(new ResizeSetariaEvent(ResizeSetariaEvent.MAXIMIZE));
			}
		}
		
		/**
		 * 窗口尺寸改变时调用
		 */
		private function resize(event:Event):void
		{
			dragAmountX=parent.mouseX - dragStartMouseX;
			dragAmountY=parent.mouseY - dragStartMouseY;
			if (currentResizeHandle == topButton && parent.mouseY > 0)
			{
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == rightButton)
			{
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
			}
			else if (currentResizeHandle == bottomButton && parent.mouseY < parent.height)
			{
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == leftButton && parent.mouseX > 0)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
			}
			else if (currentResizeHandle == topLeftButton && parent.mouseX > 0 && parent.mouseY > 0)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == topRightButton && parent.mouseX < parent.width && parent.mouseY > 0)
			{
				this.y=Math.min(savedWindowRect.y + dragAmountY, dragMaxY);
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height - dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == bottomRightButton && parent.mouseX < parent.width && parent.mouseY < parent.height)
			{
				this.width=Math.max(savedWindowRect.width + dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
			else if (currentResizeHandle == bottomLeftButton && parent.mouseX > 0 && parent.mouseY < parent.height)
			{
				this.x=Math.min(savedWindowRect.x + dragAmountX, dragMaxX);
				this.width=Math.max(savedWindowRect.width - dragAmountX, this.skin.minWidth);
				this.height=Math.max(savedWindowRect.height + dragAmountY, this.skin.minHeight);
			}
		}
		
		/**
		 * 在窗口边缘并按下鼠标左键时调用
		 */
		private function resizeButtonDown(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				currentResizeHandle=event.target as Button;
				setCursor(currentResizeHandle);
				dragStartMouseX=parent.mouseX;
				dragStartMouseY=parent.mouseY;
				savedWindowRect=new Rectangle(this.x, this.y, this.width, this.height);
				dragMaxX=savedWindowRect.x + (savedWindowRect.width - this.skin.minWidth);
				dragMaxY=savedWindowRect.y + (savedWindowRect.height - this.skin.minHeight);
				systemManager.addEventListener(Event.ENTER_FRAME, resize);
				systemManager.addEventListener(MouseEvent.MOUSE_UP, resizeButtonRelease);
				systemManager.stage.addEventListener(Event.MOUSE_LEAVE, resizeButtonRelease);
			}
		}
		
		/**
		 * 在窗口边缘并弹开鼠标左键时调用
		 */
		private function resizeButtonRelease(event:MouseEvent):void
		{
			currentResizeHandle=null;
			systemManager.removeEventListener(Event.ENTER_FRAME, resize);
			systemManager.removeEventListener(MouseEvent.MOUSE_UP, resizeButtonRelease);
			systemManager.stage.removeEventListener(Event.MOUSE_LEAVE, resizeButtonRelease);
			CursorManager.removeAllCursors();
		}
		
		/**
		 * 在窗口边缘并鼠标离开时调用
		 */
		private function resizeButtonRollOut(event:MouseEvent):void
		{
			if (!event.buttonDown)
				CursorManager.removeAllCursors();
		}
		
		/**
		 * 在窗口边缘并鼠标进入时调用
		 */
		private function resizeButtonRollOver(event:MouseEvent):void
		{
			if (sizeState == SetariaTitleWindow.STATE_NORMAL)
			{
				if (!event.buttonDown)
				{
					setCursor(event.target as Button);
				}
			}
		}
		
		/**
		 * 鼠标经过窗口边缘时设置鼠标显示形状
		 */
		private function setCursor(target:Button):void
		{
			switch (target)
			{
				case topButton:
				case bottomButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_VERTICAL, 2, -10, -10);
					break;
				case rightButton:
				case leftButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_HORIZONTAL, 2, -10, -10);
					break;
				case topLeftButton:
				case bottomRightButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_TL_BR, 2, -10, -10);
					break;
				case topRightButton:
				case bottomLeftButton:
					CursorManager.setCursor(DEFAULT_RESIZE_CURSOR_TR_BL, 2, -10, -10);
					break;
			}
		}
		
//		override protected function moveArea_mouseDownHandler(event:MouseEvent):void
//		{
//			// Only allow dragging of pop-upped windows
//			if (enabled)
//			{
//				// Calculate the mouse's offset in the window
//				// TODO (klin): Investigate globalToLocal method
//				offsetX = event.stageX - x;
//				offsetY = event.stageY - y;
//				
//				var sbRoot:DisplayObject = systemManager.getSandboxRoot();
//				
//				sbRoot.addEventListener(
//					MouseEvent.MOUSE_MOVE, moveArea_mouseMoveHandler, true);
//				sbRoot.addEventListener(
//					MouseEvent.MOUSE_UP, moveArea_mouseUpHandler, true);
//				sbRoot.addEventListener(
//					SandboxMouseEvent.MOUSE_UP_SOMEWHERE, moveArea_mouseUpHandler)
//				
//				// add the mouse shield so we can drag over untrusted applications.
//				systemManager.deployMouseShields(true);
//			}
//		}
		
		
		public function get showMaximizButton():Boolean{
			return this._maximizable;
		}
		public function set showMaximizButton(flag:Boolean):void{
			this._maximizable = flag;
		}
		public function get showMinimizButton():Boolean{
			return this._minimizable;
		}
		public function set showMinimizButton(flag:Boolean):void{
			this._minimizable = flag;
		}
		public function get resizeEnabled():Boolean{
			return this._resizable;
		}
		public function set resizeEnabled(flag:Boolean):void{
			this._resizable = flag;
		}
	}
	
}
